/*
 * @Author:zengqixin zengqixin@sailvan.com
 * @Date: 2023-11-11 
 * @LastEditors:zengqixin@sailvan.com
 * @LastEditTime: 2023-11-11
 * @FilePath: /tbox_meige/include/gsensor.h
 * @Description:gsensor:主要进行卡尔曼滤波计算以及包括震动、报警、倾斜、翻转在内的事件检测
    （1）卡尔曼滤波：计算pitch（俯仰角）和roll（翻转角）
    *R越大相信预测，Q越大越相信测量
    *dt：小——延迟，大——过冲
    *Q_angle--越大：  越小：滤波效果越显著(从小调到大）
    *R_angle:越大卡尔曼滤波响应变慢，越小收敛快但是容易发生振荡（建议：（3seigema）^2）
    *PP：越小越相信当前预测状态，决定初始收敛速度

    （2）事件处理：震动、报警、倾斜、翻转在内的事件检测
    *低功耗模式下会进行碰撞检测collide_cheke()，检测可能产生震动报警（tremedous moving warnning ）和异动报警（unusual moving warnning）。
    *正常工作模式下会进行倾斜tilt_check（）、翻转检测overturn_check（）。
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
 */


#ifndef __GSENSOR_H__
#define __GSENSOR_H__
#include <math.h>

#include "fw_interface.h"
#include "adapt.h"
#include "time.h"
#include "gsensor/gs_algorithm.h"

#define ALARM_MOVE_MASK (1 << 0)
#define ALARM_UNUSUAL_MOVE_MASK (1 << 1)    
#define ALARM_TILT_MASK (1 << 2)    
#define ALARM_ROLL_MASK (1 << 3)

/***********************************宏定义区********************************/
/*每次倾斜、翻滚检测的状态*/
#define TILT_SAFE               1
#define TILT_RISK               0
#define OVERTURN_RISK           0
#define OVERTURN_SAFE           1

/*异动检测持续时间(10S定位后取3个点*10+最大剩余时间)*/ 
#define UNUSUAL_MOVE_CHECK_TIME 36

/*数学参数*/
#define PI                  3.1415
#define RADIAN_TO_ANGLE     (16.4)
#define STRAIGHT_ANGLE      180
#define FULL_ANGLE          360
#define MOVE_TIME_DURING    30

#define MAGNIFICATION       10000000              // 放大倍数
#define MOVE_THRESHOLD      25                   // 实际测试大概值 移动20m距离
#define SPEED_TICK_COUNT    80                   //80个tick之前的速度，实测下来就是7s之前的速度

/************************结构体声明区************************************************/

typedef struct
{
    uint16_t warning_id;
    int timestamp;
    uint8_t len;
    uint8_t data;
}warning_info_st;

typedef struct
{
    bool is_located;           /* 是否定位上 */ 
    int latitude_min;          /* 纬度 北纬为正数，南纬为负数，十进制放大10000000得出结果。*/
    int latitude_max;          /* 纬度 北纬为正数，南纬为负数，十进制放大10000000得出结果。*/
    int longitude_min;         /* 经度 东经为正数，西经为负数，十进制放大10000000得出结果。*/
    int longitude_max;         /* 经度 东经为正数，西经为负数，十进制放大10000000得出结果。*/
}ST_GPS_MOVE_CHECK_INFO;

typedef enum
{
    GSENSOR_NORMAL_WORK         = 0x00, /*正常工作状态，可执行倾斜检测/翻滚检测*/
    GSENSOR_LOW_POWER           = 0x01, /*在低功耗状态下发生碰撞事件后，唤醒gsensor，并且进行震动检测与处理/异动检测与处理*/
    GSENSOR_AWAIT_PANEL_PASSWORD_INPUT                 = 0X02,/*等待输入密码的状态，未产生碰撞事件collide event，产生异动而不产生震动*/
    GSENSOR_AWAIT_PANEL_PASSWORD_INPUT_COLLIDE         = 0X03,/*等待输入密码的状态，产生碰撞事件collide event，产生异动而不产生震动*/
}EN_GSENSOR_STATE;


#define SENSITIVITY_VERY_HIGH_VALUE           20          //极高灵敏度数值
#define SENSITIVITY_PER_CLASS_VALUE           200         //每级数值

#define SENSITIVITY_LOW_LEVEL           0 
#define SENSITIVITY_MID_LEVEL           1
#define SENSITIVITY_HIGH_LEVEL          2
#define SENSITIVITY_VERY_HIGH_LEVEL     255        //等级


typedef struct
{
    float acc;       /*加速度的阈值*/
    int time;        /*防抖时间的阈值*/
    int angle;       /*角度的阈值，目前已取消机制，协议上保留*/
    int gyro;      /* 角速度阈值 */
    int vel;         /*速度的阈值*/
}ST_GSENSOR_MNG_THRSHOLID;

typedef enum
{
    EN_LW_ROAD_BIKE         =0x00, /*轻量型公路车*/
    EN_AP_MOUNTAIN_BIKE     =0X02, /*泛用型山地车*/
}EN_BIKE_FRAME_TYPE;

typedef struct
{
    float angle_pitch; /*倾斜角pitch*/
    float pitch_offset; /*补偿*/

    float angle_roll; /*翻转角roll*/
    float roll_offset; /*补偿*/
}ST_ANGLE;

typedef struct {
    short x;
    short y;
    short z;
} gyro_src_t;

typedef struct {
    short x;
    short y;
    short z;
} accel_src_t;


/* 动静检测采用最新10个数据比较 */
#define EVENT_MOTION_COMPARE_COUNT      10
/* 动静检测防抖个数 */
#define EVENT_MOTION_COMPARE_STABLE_CNT (5)


/* 检测到SENSOR运动维持120ms */
#define EVENT_MOTION_KEEP_TIME      120
/* 持续静止1000ms启动静止/运动计时 */
#define EVENT_MOTION_REST_TIME      1000
///* 动静灵敏度等级数为3级(0 1 2) */
//#define EVENT_MOTION_MAX_LEVEL      2
/* 默认灵敏度等级为1 */
#define EVEN_MOTION_LEVEL_DEFAULT   1

#define SENSOR_ACCEL_SRC_BUFFER_CONTAIN     400


typedef enum {
    MOTION_STATUS_NONE = 0,
    MOTION_STATUS_OFF,      /* 熄火运动检测 */
    MOTION_STATUS_ON,       /* 点火运动检测 */
} motion_status_e;


typedef struct
{
    bool update;                /* true数据有更新         */
    unsigned int accel_index;   /* accel下一个可写的位置  */
    accel_src_t accel[SENSOR_ACCEL_SRC_BUFFER_CONTAIN];         /* 保存最近400个加速计数据 */  
} sensor_middle_support_t;


/*************************数值处理函数************************************************/

/*gsensor模块的初始化*/
int swei_gsensor_module_init(void);

/* 默认参数赋值 */
void gsensor_thresh_init(void);

void gsensor_thresh_print(void);


extern ST_GSENSOR_DRIVER_PARA *get_gsensor_local_run_config(void);

extern ST_GSENSOR_MNG_THRSHOLID *get_gsensor_tilt_run_config(void);

extern ST_GSENSOR_MNG_THRSHOLID *get_gsensor_overturn_run_config(void);

extern int gs_tremos_thresh_during_time;
extern int gs_unusual_moving_thresh_during_time;



/*正常工作状态下gsensor的线程*/
void swei_proc_gsensor_info_handler(void);

bool swei_get_is_collide_sound_playing(void);

/*设置gsensor告警阈值*/
int tbox_gsensor_set_threshold(int threshold);

void sensor_motion_on_accel_threshold_set(int glevel);

float sensor_motion_on_accel_threshold_get(void);

void sensor_wakeup_motion_accel_threshold_set(int int_sensitivity);

float sensor_wakeup_motion_accel_threshold_get(void);

int sensor_source_data_is_update(void);

accel_src_t* accel_src_buffer_get(void);

void accel_src_buffer_wr_index_set(unsigned int idx);

unsigned int accel_src_buffer_wr_index_get(void);

unsigned int accel_src_buffer_max_count(void);

char get_gs_collide_machine_state(void);

void gsensor_module_init_prara(void);

void gsensor_app_driver_param_sync(void);



/**
 * @brief 中断处理函数
 */
void gsensor_interrupt_handler(void);

/**
 * @brief 检查中断标志
 * @return int 
 */
int gsensor_interrupt_check(void);

/**
 * @brief 清除中断标志
 */
void gsensor_interrupt_clear(void);

/**
 * @brief 震动使能
 */
void gsensor_shake_enable(void);
/**
 * @brief 震动失能
 */
void gsensor_shake_disable(void);

/**
 * @brief 异动状态检测中，关联休眠逻辑，如果为true，则不进入休眠
 * @return true  - 进行中
 * @return false 
 */
bool gsensor_unusal_move_check(void);

/**
 * @brief 检测使能
 */
uint32_t gsensor_alarm_state_get(void);


/**
 * @brief XY轴检测调换
 */
bool get_gsensor_change_gyro_xy(void);


#endif

